const { db } = require('../utils/database');

/**
 * utils
 * 就是一个模块，模块就是可以重复使用的代码块。
 */
const fs = require('fs');
const crypto = require('crypto');
// 日期转换工具 Moment.js
const moment = require('moment');
// Axios 使用
const axios = require('axios');

/**
 *
 * @function 百度AI开放平台授权调用开放API，调获取Access_token
 * @param {grant_type} 必须参数，固定为client_credentials；
 * @param {client_id} 必须参数，应用的API Key；
 * @param {client_secret} 必须参数，应用的Secret Key；
 * @returns 返回请求结果access_token等
 */
const getBaiduToken = (grant_type = 'client_credentials', client_id, client_secret) => {
	const params = {
		grant_type,
		client_id,
		client_secret
	};
	return new Promise((resolve, reject) => {
		axios({
			method: 'post',
			url: 'https://aip.baidubce.com/oauth/2.0/token',
			params
		})
			.then((res) => {
				resolve(res.data.access_token);
			})
			.catch((error) => {
				reject(error);
			});
	});
};

/**
 *
 * @function 百度AI开放平台授权调用开放API，调获取Access_token
 * @param {grant_type} 必须参数，固定为client_credentials；
 * @param {client_id} 必须参数，应用的API Key；
 * @param {client_secret} 必须参数，应用的Secret Key；
 * @returns 返回请求结果access_token等
 */
const baiduIdcard = (params) => {
	return new Promise((resolve, reject) => {
		axios
			.post('https://aip.baidubce.com/rest/2.0/ocr/v1/idcard', params, {
				headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
			})
			.then((res) => {
				resolve(res.data);
			})
			.catch((error) => {
				reject(error);
			});
	});
};

/**
 *
 * @function 百度AI开放平台授权调用开放API，调获取Access_token
 * @param {grant_type} 必须参数，固定为client_credentials；
 * @param {client_id} 必须参数，应用的API Key；
 * @param {client_secret} 必须参数，应用的Secret Key；
 * @returns 返回请求结果access_token等
 */
const ocr_idcard = async (access_token = '') => {
	const params = {
		access_token
	};
	let bool, msg, token, error;
	await axios({
		method: 'post',
		url: 'https://aip.baidubce.com/rest/2.0/ocr/v1/idcard',
		params
	})
		.then((res) => {
			bool = true;
			msg = '调用成功';
			token = res.data.access_token;
		})
		.catch((Error) => {
			bool = false;
			msg = '调用失败';
			error = Error;
		});
	return {
		success: bool,
		message: msg,
		data: {
			token,
			error
		}
	};
};

/**
 *
 * @function 把日期格式化为 2023-03-24 00:00:00
 * @param {*} time 时间
 * @param {*} str 格式化方式
 * @returns 返回格式化后的日期
 */
const dataFormat = (time, str) => {
	return moment(time).format(str);
};

/**
 * @function 当前日期减去传入日期
 * @param {*} time 传入日期
 * @param {*} str 返回的日期格式 years、weeks、days...
 * @returns 返回相减后得到的年、周、天数
 */
const dataDiff = (time, str) => {
	return moment(new Date()).diff(moment(time), str);
};

const UNUSABLE_PASSWORD = '!';
/**
 * getHexDigest 加密字符串
 *
 * @param {string} algorithm 加密算法
 * @param {string} salt 随机字符串
 * @param {string} raw 明文
 *
 * @returns {string} 密文
 */
function getHexDigest(algorithm, salt, raw) {
	let hash = crypto.createHash(algorithm);
	hash.update(salt + raw);
	return hash.digest('hex');
}

/**
 * makePassword 密码加密函数
 *
 * @param {string} rawPassword 明文密码
 * @returns 加密后的密文
 */
function makePassword(rawPassword) {
	if (rawPassword == undefined) return UNUSABLE_PASSWORD;
	let algo = 'sha1',
		rand = () => Math.random().toString(16).slice(-8),
		salt = getHexDigest(algo, rand(), rand()).slice(-8),
		hsh = getHexDigest(algo, salt, rawPassword);
	return `${algo}$${salt}$${hsh}`;
}

/**
 * checkPassword 验证密码
 *
 * @param {string} rawPassword 明文密码
 * @param {string} encPassword 密文
 * @returns {boolean}
 */
function checkPassword(rawPassword, encPassword) {
	if (encPassword == UNUSABLE_PASSWORD) return false;
	let [algo, salt, hsh] = encPassword.split('$');
	if (!algo || !salt || !hsh) return false;
	return hsh == getHexDigest(algo, salt, rawPassword);
}

const readFile = (path, options) => {
	return new Promise((resolve, reject) => {
		//
		fs.readFile(path, options, (err, data) => {
			if (err) reject(err);
			else resolve(data);
		});
	});
};

const writeFile = (file, data) => {
	return new Promise((resolve, reject) => {
		fs.writeFile(file, data, (err) => {
			if (err) reject(err);
			else resolve(true);
		});
	});
};
/**
 * 对比人员变化
 * @param {Array} originalArray
 * @param {Array} newArray
 * @returns
 */
const comparePersonArrays = (originalArray, newArray) => {
	return new Promise(async (resolve, reject) => {
		try {
			await Promise.all(
				// 遍历新数组，查找是否有管理员异常
				newArray.map(async (manager_id) => {
					let manager = await db.findOne('select * from managers where id = ?', [manager_id]);
					if (!manager || manager.status) {
						throw new Error(manager_id);
					}
				})
			);
			// 过滤出删除的和新增的
			let diffArrayDeletePerson = originalArray.filter((item) => !newArray.includes(item));
			let diffArrayAddPerson = newArray.filter((item) => !originalArray.includes(item));
			// 返回结果
			resolve({
				diffArrayDeletePerson,
				diffArrayAddPerson
			});
		} catch (error) {
			reject({
				success: false,
				message: error.message || '服务器发生未知错误！'
			});
		}
	});
};
/**
 * 对比事件标签变化
 * @param {Array} originalArray
 * @param {Array} newArray
 * @param {Number} matterId
 * @returns
 */
const compareMatterTagArrays = async (originalArray, newArray, matterId) => {
	if (!matterId) {
		throw new Error('matterId 不能为空！');
	}

	try {
		if (!originalArray.length && newArray.length) {
			// 全部新增
			for (let item of newArray) {
				let { tag_name, color = '#000', text_color = '#fff' } = item;
				await db.query('insert into matterTags (tag_name, color, text_color, matter_id) values (?,?,?,?)', [
					tag_name,
					color,
					text_color,
					matterId
				]);
			}
			return;
		} else if (originalArray.length && !newArray.length) {
			// 全部删除
			await db.query('delete from matterTags where matter_id = ?', [matterId]);
			return;
		} else {
			// 过滤出删除的和新增的
			let diffArrayDeleteTag = originalArray.filter((item) => !newArray.includes(item));
			let diffArrayAddTag = newArray.filter((item) => !originalArray.includes(item));

			// 删除
			for (let item of diffArrayDeleteTag) {
				await db.query('delete from matterTags where id = ? and matter_id = ?', [item.id, matterId]);
			}

			// 新增
			for (let item of diffArrayAddTag) {
				let { tag_name, color = '#000', text_color = '#fff' } = item;
				await db.query('insert into matterTags (tag_name, color, text_color, matter_id) values (?,?,?,?)', [
					tag_name,
					color,
					text_color,
					matterId
				]);
			}
			return;
		}
	} catch (error) {
		throw {
			success: false,
			message: '服务器发生未知错误！'
		};
	}
};

// 安照 CommonJS 规范进行导出
module.exports = {
	readFile,
	writeFile,
	getHexDigest,
	makePassword,
	checkPassword,
	dataFormat,
	dataDiff,
	getBaiduToken,
	baiduIdcard,
	comparePersonArrays,
	compareMatterTagArrays
};
